package com.thb.pay.manage.comm.aspect;


import com.thb.pay.core.annotation.LoginRequired;
import com.thb.pay.core.cache.EhcacheUtils;
import com.thb.pay.core.enums.Action;
import com.thb.pay.core.exception.RRException;
import com.thb.pay.manage.comm.utils.AdminConstants;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @Description: 登入token 注解校验
 */
@Slf4j
@Order(2)
@Component
@Aspect
public class LoginAspect {

    private static final String TOKEN = "token";// token 校验


    public static LoginRequired getRequired(ProceedingJoinPoint joinPoint) throws Exception {
        Signature sig = joinPoint.getSignature();
        Method m = joinPoint.getTarget().getClass().getMethod(joinPoint.getSignature().getName(), ((MethodSignature) sig).getParameterTypes());
        LoginRequired loginRequired = m.getAnnotation(LoginRequired.class);
        return loginRequired;
    }

    /**
     * 切点
     */
    @Pointcut("@annotation(com.thb.pay.core.annotation.LoginRequired)")
    public void loginPointcut() {
    }

    /**
     * 切面
     *
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("loginPointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        // 使用point.getArgs()可获取request，仅限于spring MVC参数包含request，改为通过contextHolder获取。
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        LoginRequired required = getRequired(point);
        if (required == null || required.value().equals(Action.Normal)) {
            //没 注解  + 需要强制校验
            checkLogin(request);
        }
        Object result = point.proceed();
        return result;
    }

    /**
     * 检查调用凭证
     *
     * @param request
     */
    public boolean checkLogin(HttpServletRequest request) {
        String accessToken = request.getHeader(TOKEN); //请求 header token
        if (StringUtils.isEmpty(accessToken)) {
            throw RRException.build("token.is.not.null");
        }
        //校验token是否过期
        Object accessUserObj = EhcacheUtils.getInstance().get(AdminConstants.getCacheAccessTokenKey(accessToken));
        if (accessUserObj == null) {
            throw RRException.build("access.token.expire");
        }
        return true;
    }

}
